# -*- coding: utf-8 -*-
import atexit
import sys
import ssl
from pyVim.connect import Disconnect, SmartConnect
from pyVmomi import vim
from pyVim.task import WaitForTask

# vCenter信息
vcenter_ip = "172.16.100.57"
vcenter_port = "443"
vcenter_user = "administrator@vsphere.local"
vcenter_pwd = "Shsnc123!@#"

# 定义要克隆的虚拟机和目标位置
src_vm_name = 'python测试模板机'
dest_vm_name = 'snc-test-imp'
datastore_name = "datastore_100.54"

class vCenterManager():
    def __init__(self, vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd):
        self.vcenter_ip = vcenter_ip
        self.vcenter_port = vcenter_port
        self.vcenter_user = vcenter_user
        self.vcenter_pwd = vcenter_pwd
        self.context = None
        self.si = None
        self.content = None

        # 建立与vSphere的连接
        if hasattr(ssl, '_create_unverified_context'):
            self.context = ssl._create_unverified_context()
        self.si = SmartConnect(host=self.vcenter_ip, port=self.vcenter_port,
                               user=self.vcenter_user, pwd=self.vcenter_pwd,
                               sslContext=self.context)
        if not self.si:
            print("请检查vc账号密码")
            sys.exit(1)

        self.content = self.si.RetrieveContent()
        atexit.register(Disconnect, self.si)

    def vm_clone(self, src_vmname, dest_vmname, datastore_name):
        if not src_vmname or not dest_vmname:
            print("源或目标虚拟机设置错误")
            sys.exit(1)

        # 查找源虚拟机对象
        src_vm = self.get_obj(self.content, [vim.VirtualMachine], src_vmname)
        if not src_vm:
            raise SystemExit("源虚拟机未找到")

        # 配置目标存储位置
        datastore = self.get_obj(self.content, [vim.Datastore], datastore_name)
        if not datastore:
            raise SystemExit("存储地址未找到")

        relocate_spec = vim.vm.RelocateSpec(datastore=datastore)

        # 创建自定义规格
        customization_spec = self.create_customization_spec(
            dest_vm_name,
            ip_address="172.16.100.250",
            gateway=["172.16.100.1"],
            dns=["8.8.8.8"],
            subnet_mask="255.255.255.0"
        )

        # 克隆配置
        clone_spec = vim.vm.CloneSpec(
            powerOn=False,
            template=False,
            location=relocate_spec,
            customization=customization_spec
        )

        # 执行克隆任务
        print("开始克隆虚拟机...")
        task = src_vm.CloneVM_Task(folder=src_vm.parent, name=dest_vmname, spec=clone_spec)
        WaitForTask(task)
        print("虚拟机克隆完成")

    @staticmethod
    def get_obj(content, vimtype, name):
        """获取vSphere对象"""
        obj = None
        container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
        for c in container.view:
            if c.name == name:
                obj = c
                break
        container.Destroy()
        return obj


    @staticmethod
    def create_customization_spec(hostname, ip_address, gateway, dns, subnet_mask):
        """创建自定义规格"""
        # 网络适配器设置
        adapter_map = vim.vm.customization.AdapterMapping()
        adapter_map.adapter = vim.vm.customization.IPSettings(
            ip=vim.vm.customization.FixedIp(ipAddress=ip_address),
            subnetMask=subnet_mask,
            gateway=gateway,
            dnsServerList=dns
        )

        # 全局IP设置
        global_ip = vim.vm.customization.GlobalIPSettings(dnsServerList=dns)

        # Linux系统标识
        identity = vim.vm.customization.LinuxPrep(
            domain="local",
            hostName=vim.vm.customization.FixedName(name=hostname)
        )

        # 自定义规格
        customization_spec = vim.vm.customization.Specification()
        customization_spec.nicSettingMap = [adapter_map]
        customization_spec.globalIPSettings = global_ip
        customization_spec.identity = identity

        return customization_spec


if __name__ == '__main__':
    vc = vCenterManager(vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd)
    vc.vm_clone(src_vm_name, dest_vm_name, datastore_name)
